package com.github.baichuan.iot.protocol.jt808.codec;

import com.github.baichuan.iot.protocol.codec.MessageException;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

public class Delimiter {

    /**
     * 发送消息时进行报文转义
     * 将 0x7D 转义 为 0x7D 0x01
     * 将 0x7E 转义 为 0x7D 0x02
     */
    public static ByteBuf escape(ByteBuf buf){
        int length = buf.readableBytes();
        ByteBuf result = Unpooled.buffer(length + 4);

        for(int i = 0; i < length; i++) {
            short value = buf.readUnsignedByte();
            if(i == 0 || i == length - 1) {
                result.writeByte(value);
                continue;
            }

            switch (value) {
                case 0x7e:
                    result.writeBytes(new byte[] {0x7d, 0x02});
                    break;
                case 0x7d:
                    result.writeBytes(new byte[] {0x7d, 0x01});
                    break;
                default:
                    result.writeByte(value);
                    break;
            }
        }

        return result;
    }

    /**
     * 接收消息时进行报文还原转义
     * 将 0x7D 0x01 还原 为 0x7D
     * 将 0x7D 0x02 还原 为 0x7E
     */
    public static ByteBuf unescape(ByteBuf buf) {
        ByteBuf result = Unpooled.buffer(buf.readableBytes());

        while (buf.readableBytes() > 0){
            short value = buf.readUnsignedByte();

            if(value == 0x7d) {
                short next = buf.readUnsignedByte();
                switch (next) {
                    case 0x01:
                        result.writeByte(0x7d);
                        break;
                    case 0x02:
                        result.writeByte(0x7e);
                        break;
                    default:
                        throw new MessageException("报文转义错误：0x7d 0x" + Integer.toHexString(next));
                }
            } else {
                result.writeByte(value);
            }
        }

        return result;
    }
}
